<template>
	<view>

		<!-- 商品轮播图片 -->
		<view class="goods-head">
			<uv-swiper :list="goods.slider" height="100%" :circular="true" :indicator="true" :radius="0"
				indicatorStyle="right" :loading="loading" />

			<!-- <swiper circular :autoplay="true" :indicatorDots="true" class="full">
				<swiper-item v-for="xx, ii in goods.slider" :key="`slider${ii}`">
					<uv-image :src="xx" height="100%" width="100%" radius="10rpx" :fade="true" />
				</swiper-item>
			</swiper> -->

		</view>

		<view style="position:absolute;top:30rpx;right:30rpx;zoom:0.8">
			<template v-if="goods.level_upgrade == 0">
				<uv-tags shape="circle" type="success" size="mini" text="入会礼包" />
			</template>
			<template v-if="goods.level_upgrade > 0">
				<uv-tags shape="circle" type="error" size="mini" :text="`升级VIP${goods.level_upgrade}`" />
			</template>
		</view>

		<!-- 当前选择规格及价格 -->
		<uv-skeleton :title="false" rows="3" :loading="loading">
			<view class="goods-info flex-x">
				<view class="flex-1">
					<view class="tn-text-bold">{{ goods.name }}</view>
					<view class="flex tn-mt-sm tn-text-sm" @click="showSpec(1)">
						<view>已选规格：</view>
						<view class="flex-1 flex-x">
							<view class="tn-mr-xs" v-for="xx in check" :key="xx.unid">{{ xx.name }}</view>
							<uv-icon color="white" size="20rpx" name='arrow-right' />
						</view>
					</view>
				</view>
				<view>
					<view class="flex-y tn-text-right">
						<uv-text mode="price" align="center" :bold="true" size="35rpx" color="#fff"
							:text="select.price_selling" />
						<uv-text mode="price" align="center" color="#fff" size="20rpx" :text="select.price_market"
							customStyle="margin-top:10rpx;text-decoration:line-through;" />
					</view>
				</view>
			</view>
		</uv-skeleton>

		<!-- 商品富文本详情 -->
		<view class="goods-body">
			<uv-parse :content="goods.content" :preview-img="false" :tagStyle="{ img: 'display:flex;margin:0 auto' }" />
		</view>

		<!-- 商品购买按钮 -->
		<view class="goods-foot tn-shadow-md" v-if="!loading">
			<uv-transition :show="!loading" mode="slide-bottom">
				<view class="flex-x">

					<view class="flex-1 flex-x tn-white_bg" style='width:350rpx'>

						<view class="flex-center flex-y" style="height:100rpx;" @click="goto.home()">
							<uv-icon name="home" size="45rpx" color="error" />
							<text class="tn-text-sm tn-gray_text">首页</text>
						</view>

						<view class="flex-center flex-y" style="height:100rpx;" @click="setCollect()">
							<uv-icon v-if="isCollect" size="45rpx" name="star-fill" color="error" />
							<uv-icon v-else name="star" size="45rpx" color="error" />
							<text class="tn-text-sm tn-gray_text">{{ isCollect ? '已收藏' : '收藏' }}</text>
						</view>

						<view class="flex-center flex-y" style="height:100rpx;" @click="goto.cart()">
							<text style="font-size:35rpx;" class="tn-red_text">
								{{ userinfo?.extra?.mycarts_total || 0 }}
							</text>

							<text class="tn-text-sm tn-gray_text">购物车</text>
						</view>

					</view>

					<uv-button type="warning" @click="showSpec(2)" text="加入购物车"
						customStyle="width:200rpx;height:100rpx;border-radius:0" />

					<uv-button type="error" @click="showSpec(1)" text="立即购买"
						customStyle="width:200rpx;height:100rpx;border-radius:0" />
				</view>
			</uv-transition>
		</view>

		<!-- 商品规格选择器 -->
		<uv-popup ref="specs" mode="bottom" :closeable="true" round="10rpx" bgColor="#fcfcfc" customStyle="overflow:hidden">
			<view class="tn-p tn-text-center">
				{{ mode === 1 ? '提交订单' : '加入购物车' }}
			</view>
			<view class="tn-p-sm relative">

				<view class="flex-x tn-p-sm tn-radius tn-white_bg tn-shadow-md">
					<view class="tn-mr-sm">
						<uv-image width="180rpx" height="180rpx" :fade="true" radius="10rpx"
							:src="select.gimage || goods.cover" />
					</view>
					<view class="flex-1 flex-y">
						<view class="tn-text-bold" style="font-size:30rpx">{{ goods.name }}</view>
						<view class="flex-x flex-center tn-mt-sm">
							<view>
								<uv-text mode="price" size="35rpx" color="#bf0d0d" :bold="true"
									:text="select.price_selling" />
							</view>
							<view v-if="select.gunit" style="font-size:24rpx;color:#bf0d0d">/{{ select.gunit }}</view>
							<uv-tags v-if="select.price_diff > 0" size="mini" shape="circle" class="tn-ml-xs" color="#fff"
								bgColor="#bf0d0d" borderColor="#bf0d0d" :text="`已优惠 ${select.price_diff} 元`" />
							<view class="flex-1"></view>
						</view>
						<view class="flex-x ta-desc-color tn-mt-sm" style="font-size:25rpx;">
							<view class="nowrap">已选择：</view>
							<view class="nowrap tn-mr-xs" v-for="xx in check" :key="xx.unid">{{ xx.name }}</view>
						</view>
					</view>
				</view>
				<view class="tn-p-sm tn-radius tn-mt-sm tn-white_bg tn-shadow-md">
					<!-- 商品规格 -->
					<scroll-view scroll-y="true" style="max-height:40vh">
						<view v-for="(s, i) in goods.specs" :key="s.unid" class="flex-y tn-mb-sm">
							<uv-text :text="s.name" :bold="true" margin="0 0 0 8rpx" />
							<view class="flex-x tn-mt-xs flex-wrap tn-text-sm">
								<view v-for="(ss, ii) in s.list" :key="ss.unid" if-show="ss.show && ss.check"
									class="tn-pr-xs tn-mb-xs">
									<uv-button shape="circle" plain @click="setSpec(i, ii)" :text="ss.name"
										:type="ss.select ? 'error' : 'info'"
										customStyle="font-size:24rpx;height:45rpx;padding:20rpx 15rpx" />
								</view>
							</view>
						</view>
					</scroll-view>

					<!-- 购买数量 -->
					<view class="flex-align-center flex-x-between tn-mt-xs" style="height:80rpx;">
						<uv-text text="购买数量" :bold="true" margin="0 0 0 8rpx" />
						<view v-if="nummax > 0">
							<uv-number-box :min="1" :max="nummax" v-model="number" />
						</view>
						<view v-else class="tn-p-sm">
							<text class="tn-red_text tn-text-sm">已售完</text>
						</view>
					</view>

					<view class="tn-mt">

						<!-- 已登录 -->
						<view v-if="isLogin" class="tn-p-xs tn-white_bg tn-mt-sm tn-shadow tn-round"
							style="background:rgba(191,13,13,0.9)">
							<view class="flex-x-between">

								<view class="flex-y tn-pl-lg">
									<uv-text mode="price" :bold="true" size="35rpx" color="#FFF"
										:text="select.price_selling * number" />
									<view class="tn-text-xs" style="color:rgba(255,255,255,0.8)">
										<text>共 {{ number }} {{ select?.gunit }}商品</text>
										<text v-if="select.price_diffs">，已优惠 {{ select.price_diffs }} 元</text>
									</view>
								</view>

								<view class="flex-1">

									<uv-button @click="confirmBuy" v-if="mode === 1" shape="circle" type="info"
										customStyle="width:220rpx;height:85rpx;color:rgb(191,13,13)" :disabled="nummax < 1"
										text="提交订单" />

									<uv-button @click="confirmCart" v-if="mode === 2" shape="circle" type="info"
										customStyle="width:220rpx;height:85rpx;color:rgb(191,13,13)" text="加入购物车" />

								</view>
							</view>
						</view>

						<!-- 未登录 -->
						<view v-if="!isLogin" class="flex-center tn-mt-sm">
							<uv-button @click="doLogin" shape="circle" type="error" text="请 登 录"
								customStyle="width:400rpx;height:100rpx;" />
						</view>
					</view>

				</view>

			</view>
		</uv-popup>

	</view>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { TaMd5, TaToast, TaUseAccount, TaLoading, TaDataUser, TaDataOrder, TaDataGoods, TaDataActionHistory, TaDataActionCollect } from '@/utils';

export default defineComponent({
	setup() {
		return TaUseAccount(false)
	},
	data() {
		return {
			mode: <number>1,
			gcode: <string>'',
			ghash: <string>'',
			goods: <any>{},
			number: <number>1,
			nummax: <number>999,
			specs: <any>{},
			check: <any[]>[],
			select: <any>{},
			// 当前数据状态
			loading: <boolean>true,
			isLogin: <boolean>TaDataUser.isLogin(),
			isCollect: <boolean>false,
			// 规格图片属性
			gimages: <any[]>[],
			gimagei: <number>0,
			gimageb: <boolean>false,
		}
	},
	watch: {
		specs: {
			deep: true,
			handler(value: any) {
				let check: any[] = [], unids: any[] = []
				let specs = JSON.parse(JSON.stringify(value))
				// 动态读取规格属性
				specs.forEach((x: any) => x.list.forEach((xx: any) => {
					xx.select && check.push(xx) && unids.push(xx.unid)
				}))
				// 计算商品 GHASH 并同时切换选项
				if ((this.check = check).length > 0) {
					this.setHash(TaMd5(this.goods.code + '#' + unids.sort().join(';')))
				}
			}
		}
	},
	onLoad(options: any) {
		this.gcode = options.code || ''
		this.ghash = options.hash || ''
		if (this.gcode.length < 1 || this.gcode.indexOf('G') !== 0) {
			TaToast.error("无效商品编号！").then(() => this.goto.home())
		} else {
			this.loadGoods();
		}
	},
	onShow() {
		// 判断用户是否已登录
		this.isLogin = TaDataUser.isLogin();
	},
	onPullDownRefresh() {
		this.loadGoods()
		setTimeout(() => uni.stopPullDownRefresh(), 1000)
	},
	methods: {
		doLogin() {
			TaDataUser.logout();
		},
		// 初始化选择
		syncSpec(ghash: string) {
			if (ghash) {
				// 自动选中 GHASH 
				let specs: any[] = [];
				this.goods.specs.map((x: any) => {
					x.list.map((xx: any) => xx.select = false)
					specs.push(x.list)
				})
				let isFind = specs.reduce((a, b) => {
					let res: any[] = [];
					return a.map((x: any[]) => b.map((y: any[]) => res.push(x.concat(y)))), res;
				}, [[]]).some((x: any[]) => {
					let unids: any[] = [];
					x.map((y: any) => unids.push(y.unid))
					let hash = TaMd5(this.goods.code + '#' + unids.sort().join(';'));
					if (ghash === hash) return x.map((y: any) => y.select = true), true;
				})
				isFind || TaToast.error('商品规格不存在！')
			}
			if (!ghash) {
				/* 选中默认规格 */
				this.goods.specs.map((x: any) => x.list.map((xx: any, ii: number) => xx.select = ii === 0));
			}
			this.specs = this.goods.specs;
		},
		changeSpecByHash(e: any) {
			this.syncSpec(this.gimages[e.current].ghash);
		},
		// 显示规格选择器
		showSpec(mode: number) {
			this.mode = mode;
			// @ts-ignore
			this.$refs.specs.open();
		},
		closeSpec() {
			// @ts-ignore
			this.$refs.specs.close();
		},
		// 动态切换规格
		setSpec(i: number, ii: number) {
			this.specs[i].list.forEach((xx: any, _ii: number) => xx.select = ii === _ii)
		},
		// 设置选择对象
		setHash(hash: string) {
			if (this.goods.items.some((x: any, i: number) => x.ghash === hash && (this.gimagei = i, this.select = x))) {
				this.select.price_diff = Number(this.select.price_market) - Number(this.select.price_selling);
				this.select.price_diffs = Number((this.select.price_diff * this.number).toFixed(2));
				this.nummax = Math.min(this.select.stock_total - this.select.stock_sales, 9999);
			}
		},
		// 获取收藏状态
		getCollect() {
			TaDataActionCollect.get({ gcode: this.gcode }).then((ret: any) => {
				this.isCollect = ret.data.list.length > 0;
			})
		},
		// 切换收藏状态
		setCollect() {
			if (this.isCollect) {
				this.isCollect = false;
				TaDataActionCollect.del(this.gcode).catch(() => this.isCollect = true);
			} else {
				this.isCollect = true;
				TaDataActionCollect.set(this.gcode).catch(() => this.isCollect = false);
			}
		},
		// 加载商品数据
		loadGoods() {
			// 刷新收藏状态
			this.isLogin && this.getCollect();
			// 加载商品数据
			TaDataGoods.withGoods(this.gcode).then((ret: any) => {
				if (ret.data.list.length > 0) {
					this.goods = ret.data.list[0];
					// 商品规格图片处理
					let gimages: any[] = [], showSpecImage: boolean = true;
					this.goods.items.some((x: any) => {
						if (!x.gimage) return !(showSpecImage = false);
						gimages.push({ image: x.gimage || this.goods.cover, ghash: x.ghash });
					});
					if (this.gimageb = showSpecImage) {
						this.gimages = gimages;
					}
					this.loading = false;
					this.syncSpec(this.ghash);
					// 记录访问历史
					this.isLogin && TaDataActionHistory.set(this.gcode)
				}
			})
		},
		// 直接购买
		confirmBuy() {
			TaDataOrder.add({ rules: this.select.ghash + ':' + this.number })
		},
		// 加入购物车
		confirmCart() {
			TaLoading.show('添加中...')
			TaDataOrder.cartSet({ ghash: this.select.ghash, number: this.number }).then(() => {
				// @ts-ignore
				this.$refs.specs.close();
				this.number = 1;
				this.loadUser();
				TaToast.success('添加成功!');
			}).finally(() => TaLoading.hide())
		}
	}
})
</script>


<style lang="scss">
.goods {
	&-head {
		height: 450rpx;
	}

	&-info {
		color: white;
		padding: 30rpx 20rpx;
		background: rgb(191, 13, 13);
	}

	&-foot {
		left: 0;
		right: 0;
		bottom: 0;
		display: flex;
		position: fixed;
		align-items: center;
		justify-content: center;
	}
}
</style>